# 需求:NAS-Gitea-EE-27.3.4-管理侧两个坏端点-admin-user-delete-CLI-panic-+-GET-admin-users-{u}-405

状态: accepted(2026-10-20 引擎侧坏端点,绕法已落地但引擎未修;归入模板/基建修复波)
归属: 公司基建(NAS Gitea)
来源: 登记缺口(ops/products/)
日期: 2026-10-16
建议: 做,2026-10-16 做入职中间件时实测:①sudo docker exec -u git 1Panel-gitea-C0Xq gitea admin user delete --username X 直接 panic(panic: no config dyn value getter,ee/modules/setting.EnableUserGroups → models/organization.getUserAccessibleOrgIDs),exit=2,CLI 删号这条路是坏的;②GET /api/v1/admin/users/{u} 返回 405(该构建不暴露单用户管理端点),导致 must_change_password 等字段无法回读,只能改用行为判据复验;③DELETE /api/v1/admin/users/{u} 对仍在组织里的账号返回 422 user still has membership of organizations,看似合理但错误信息只给 uid,排查成本高。绕法已全部落地在 onboard-hub/scripts(gitea 侧一律走 API + 回收清单必须含退组织 + 改密走行为复验),但引擎侧的坏端点值得修或升级,否则每个新项目都会再踩一遍。

## 现状

2026-10-16 做入职中间件(onboard-hub)时在 NAS Gitea 上逐条实测,**三个管理侧问题**(不是推断,都有回包/堆栈):

1. **CLI 删号直接 panic**:`sudo docker exec -u git 1Panel-gitea-C0Xq gitea admin user delete --username <u>` → `panic: no config dyn value getter`,栈顶 `modules/setting/config.(*Option[...]).Value` → `ee/modules/setting.EnableUserGroups` → `models/organization.getUserAccessibleOrgIDs` → `services/user.DeleteUser`,**exit=2**,账号未被删除;`--purge` 同样。
2. **单用户管理端点 405**:`GET /api/v1/admin/users/{username}` 返回 **405**;`GET /api/v1/users/{username}` 与 `GET /api/v1/admin/users`(列表)**都不含 `must_change_password` 字段**。结果:「首登强制改密」这个标志无法回读,只能改用行为判据(同一账号的令牌是否还被 `You must change your password` 拒绝)复验。
3. **删号对「仍在组织」的账号报 422**:`DELETE /api/v1/admin/users/{u}` → `422 {"message":"user still has membership of organizations [uid: 20]"}`。行为本身合理(要先退组织),但错误信息只给 uid、不给账号名与组织名,排查成本高。

附带一条**正向能力确认**(供跨项目复用):容器内 `gitea admin user create / generate-access-token --raw --scopes / list` 都正常,`user list` 的 `IsActive` 列可直接当停用复验判据;`PATCH /api/v1/admin/users/{u} {"active":false}` 停用正常。

## 方案

1. **引擎侧(首选)**:①修 `gitea admin user delete` 的 panic(根因形态:EE 代码在 CLI 上下文里读动态配置项,`EnableUserGroups` 依赖的 config dyn getter 未初始化);②补/恢复 `GET /api/v1/admin/users/{username}`(或让用户对象带 `must_change_password`),让「首登强制改密」可机检;③`still has membership of organizations` 的错误信息带上账号名与组织名。
2. **升级路径(次选)**:若上游已修,评估把 NAS 上 `commitgo/gitea-ee:27.3.4` 升到修复版;升级前先备份 Gitea 库(容器 `1Panel-mysql-JnwF`),升级后跑一遍 `onboard-hub/scripts/selftest.sh`(CONFIRM=1,15 步)确认这四条行为没变。
3. **消费侧绕法(已落地,不等引擎)**:`onboard-hub/scripts/nas-user-revoke.sh` 删号一律走 `DELETE /api/v1/admin/users/{u}?purge=`;`nas-org-remove.sh` 提供「退组织」并写进离职回收清单(顺序:停用 → 退组织 → 删除);`nas-user-passwd.sh` 改密用行为判据复验。别的新项目要动 NAS 账号,直接复刻这三条,不必重新踩。
4. **代做边界**:本票属 NAS 基建(修引擎/升级),动的是 NAS 上共享的 Gitea 服务 → **只报不改**;消费侧绕法已由本会话落地并在真机自检通过。

## 验收标准

- [ ] `sudo docker exec -u git <gitea 容器> gitea admin user delete --username <临时账号>` 退出码 0 且账号消失(**不再 panic**),`--purge` 同样
- [ ] 「首登强制改密」标志能机检读取(方式不限;2026-10-20 更正:EE 27.3.8 的 API 面**本来就没有** `GET /admin/users/{username}`,不能拿它返回 200 当验收条件)
- [ ] `DELETE /api/v1/admin/users/{已退组织的账号}` 返回 204;对仍在组织的账号返回 422 时,`message` 里含账号名与组织名
- [ ] 修复或升级后,`CONFIRM=1 bash onboard-hub/scripts/selftest.sh` 仍 **15/15 通过**(确认修端点没改掉既有行为)

## 2026-10-20 复验与更正(推翻本票两处判断,别照旧结论走)

老板 11:49 追问「这个不是 1panel 提供的吗」,我把部署事实与 API 面重查了一遍,结论**改两条、留一条**:

1. **镜像是官方 EE,不是「自建构建」**:容器 labels 显示由 **1Panel 应用商店安装**(`createdBy: Apps`),compose 里 `image: commitgo/gitea-ee:27.3.8`;镜像 labels 为 `org.opencontainers.image.source=https://corp.gitea.com/gitea-ee/gitea`、`revision=76e6077`、digest `sha256:d0ab45b8…`、构建于 2026-10-10。原票「该构建不暴露单用户管理端点」「像是自建 Gitea」的判断**不成立** —— panic 栈里的 `/cache/act_workdir/<hash>/hostexecutor/…` 是官方发布物自带的编译路径(上游 CI 用 Actions runner 编译)。
2. **`GET /api/v1/admin/users/{u}` 的 405 不是坏端点**:本实例 `/swagger.v1.json` 里该路径只有 `delete,patch`,**没有 `get`**,405 是正确行为。读用户信息走 `GET /api/v1/users/{username}`(公开,实测 200)或 `GET /api/v1/admin/users` 列表(200)。真正没解决的只剩「列表与公开对象都不含 `must_change_password`」。
3. **真 bug 只剩 CLI 删号 panic,且不是配置能绕的开关**:用**存在的**账号必 panic(`panic: no config dyn value getter`,`services/user.DeleteUser` → `ee/modules/setting.EnableUserGroups`),账号**不被删除**;用不存在的账号则干净报 `user does not exist`(所以判据必须拿真账号跑)。注入 `GITEA__ee__ENABLE_USER_GROUPS=false` 仍 panic。Docker Hub 上 `commitgo/gitea-ee` 最新 tag 就是 **27.3.8**(2026-10-10),无已修版本可升。
4. **绕法实测回包(2026-10-20)**:`DELETE /api/v1/admin/users/zz-probe` → **204** 且账号即刻消失;`GET /api/v1/admin/users?limit=3` → 200;`GET /api/v1/users/linxianqinwork` → 200。即删号/查号都不缺手段,缺的只是那条 CLI 命令;`must_change_password` 继续用行为判据。
5. **处置建议**:不换镜像(EE→CE 涉用户组数据与许可证,且当前无已修版本可升),维持「删号走 API」;上游发新 EE 后再复验这条 panic。模板仓已同步更正 `docs/NAS-GITEA-ACCOUNT-OPS.md`(commit `c03ec4c`)。
